// utils/request.js

// 参数
// url: options.url,
// baseUrl:options.baseURL
// data: options.data,
// method: options.method || "GET",
// header: options.header,
// timeout: timeout,
// dataType: options.dataType || "json",
// responseType: options.responseType,

// 引入所需的工具函数
import { formatToLocalDateTime } from "./date";
import {
  getToken,
  isValidToken,
  setTokenWithTimestamp,
  setRefreshToken,
  getRefreshToken,
} from "./auth";

// 基础配置
// const BASE_URL = "http://localhost:8080"; // 本地开发
const BASE_URL = "http://1342c8c5.r3.cpolar.top";
const DEFAULT_TIMEOUT = 15000;

// Token刷新相关
let isRefreshing = false;
let refreshSubscribers = [];

// 添加请求到刷新队列
const subscribeTokenRefresh = (callback) => {
  refreshSubscribers.push(callback);
};

// 执行队列中的请求
const onTokenRefreshed = (token) => {
  refreshSubscribers.forEach((callback) => callback(token));
  refreshSubscribers = [];
};

// 刷新token函数
const refreshToken = () => {
  console.log("正在刷新token...", getRefreshToken());
  return new Promise((resolve, reject) => {
    uni.request({
      url: BASE_URL + "/auth/wx/refreshToken",
      method: "POST",
      timeout: 5000,
      header: {
        "Content-Type": "application/json",
        refresh: getRefreshToken(),
      },
      withCredentials: true, // 确保发送Cookie
      // 不同平台下保证携带Cookie的配置
      sslVerify: true, // 验证SSL证书
      success: (res) => {
        console.log("刷新token响应:", res);
        if (res.statusCode === 200 && res.data.success) {
          // 使用新函数设置token并记录时间戳
          setTokenWithTimestamp(res.data.data.token);
          console.log("刷新token成功:", res.data.data);
          setRefreshToken(res.data.data.refreshToken);
          resolve(res.data.data.token);
        } else {
          console.error("刷新token失败:", res.data);
          reject(new Error("刷新token失败"));
        }
      },
      fail: (err) => {
        console.error("刷新token请求失败:", err);
        reject(err);
      },
    });
  });
};

// 处理日期范围参数
const handleDateRange = (params) => {
  if (!params) return params;

  const newParams = { ...params };
  if (newParams.dateRange && Array.isArray(newParams.dateRange)) {
    const [startTime, endTime] = newParams.dateRange;
    newParams.startTime = startTime
      ? formatToLocalDateTime(startTime)
      : undefined;
    newParams.endTime = endTime ? formatToLocalDateTime(endTime) : undefined;
    delete newParams.dateRange;
  }
  return newParams;
};

// 登出函数
const logout = () => {
  // 清除token
  uni.removeStorageSync("token");
  // 清除token时间戳
  uni.removeStorageSync("tokenTimestamp");
  // 清除refreshToken
  uni.removeStorageSync("refresh_token");

  // 跳转到登录页
  uni.showToast({
    title: "登录已过期，请重新登录",
    icon: "none",
    duration: 2000,
  });

  setTimeout(() => {
    uni.navigateTo({
      url: "/pages/login/login",
    });
  }, 1500);
};

// 创建请求函数
const request = (config) => {
  return new Promise((resolve, reject) => {
    // 克隆配置，避免修改原始配置
    const options = { ...config };
    options.data = config.data;
    console.log("请求参数:", options.data);
    // 处理URL
    options.url = (options.baseURL || BASE_URL) + (options.url || "");
    // 处理请求头
    options.header = options.header || {};
    // 处理token
    const token = getToken();
    if (token && !options.skipToken) {
      // 验证token是否有效 - 使用简化验证方法
      console.log("Token已过期，正在刷新...", isValidToken(token));
      if (!isValidToken(token) && !options.url.includes("/auth/")) {
        // token已过期，需要刷新
        if (!isRefreshing) {
          // 开始刷新token
          isRefreshing = true;
          refreshToken()
            .then((newToken) => {
              isRefreshing = false;

              if (newToken) {
                // 刷新成功，使用新token
                onTokenRefreshed(newToken);
                options.header["Authorization"] = `Bearer ${newToken}`;
                // 重新发送请求
                // executeRequest(options, resolve, reject);
              } else {
                // 刷新失败，跳转到登录页
                logout();
                reject(new Error("登录已过期"));
              }
            })
            .catch(() => {
              isRefreshing = false;
              logout();
              reject(new Error("登录已过期"));
            });

          // 将请求添加到队列
          return subscribeTokenRefresh((token) => {
            options.header["Authorization"] = `Bearer ${token}`;
            executeRequest(options, resolve, reject);
          });
        } else {
          // 其他请求等待token刷新完成
          return subscribeTokenRefresh((token) => {
            options.header["Authorization"] = `Bearer ${token}`;
            executeRequest(options, resolve, reject);
          });
        }
      } else {
        // token有效，添加到请求头
        options.header["Authorization"] = `Bearer ${token}`;
      }
    }

    // 处理GET请求参数
    if (options.method === "GET" || options.method === undefined) {
      if (options.params) {
        const queryString = Object.keys(options.params)
          .filter(
            (key) =>
              options.params[key] !== undefined && options.params[key] !== ""
          )
          .map(
            (key) =>
              `${encodeURIComponent(key)}=${encodeURIComponent(
                options.params[key]
              )}`
          )
          .join("&");

        if (queryString) {
          options.url += (options.url.includes("?") ? "&" : "?") + queryString;
        }
      }
    }

    // 处理参数
    if (options.params) {
      options.data = handleDateRange(options.params);
    }

    if (options.data) {
      options.data = handleDateRange(options.data);
    }

    // 发送请求
    executeRequest(options, resolve, reject);
    console.log("请求参数：", options);
  });
};

// 执行请求的函数
const executeRequest = (options, resolve, reject) => {
  // 请求超时时间
  const timeout = options.timeout || DEFAULT_TIMEOUT;
  console.log("执行请求参数:", options.data);
  // 设置通用配置
  options.withCredentials = true; // 所有请求都携带Cookie
  options.sslVerify = true; // 验证SSL证书

  // 发送请求
  const requestTask = uni.request({
    url: options.url,
    data: options.data,
    method: options.method || "GET",
    header: options.header,
    timeout: timeout,
    dataType: options.dataType || "json",
    responseType: options.responseType,
    withCredentials: true, // 确保发送Cookie
    sslVerify: true, // 验证SSL证书
    success: (res) => {
      // 如果是二进制流，直接返回响应对象
      if (
        options.responseType === "blob" ||
        options.responseType === "arraybuffer"
      ) {
        resolve(res);
        return;
      }
      const response = res.data;

      // 检查响应状态
      if (!response.success && response.success !== undefined) {
        uni.showToast({
          title: response.message || "请求失败",
          icon: "none",
          duration: 2000,
        });

        if (response.status === "401") {
          refreshToken()
            .then((newToken) => {
              if (newToken) {
                // 更新配置中的token
                options.header["Authorization"] = `Bearer ${newToken}`;
                // 重新发送请求
                executeRequest(options, resolve, reject);
              } else {
                logout();
                reject(new Error("登录已过期"));
              }
            })
            .catch(() => {
              logout();
              reject(new Error("登录已过期"));
            });
          return;
        }

        reject(response);
        return;
      }

      resolve(response);
    },
    fail: (err) => {
      // 处理错误
      let errorMsg = "网络请求失败";

      if (err.errMsg.includes("timeout")) {
        errorMsg = "请求超时";

        // 超时重试
        const retryCount = options.__retryCount || 0;
        const maxRetries = options.retry || 2;
        const retryDelay = options.retryDelay || 1000;

        if (retryCount < maxRetries) {
          options.__retryCount = retryCount + 1;

          setTimeout(() => {
            executeRequest(options, resolve, reject);
          }, retryDelay);
          return;
        }
      }

      // 显示错误信息
      uni.showToast({
        title: errorMsg,
        icon: "none",
        duration: 2000,
      });

      reject({
        success: false,
        message: err.errMsg || errorMsg,
        errorCode: "NETWORK_ERROR",
        data: null,
      });
    },
  });

  // 处理取消请求
  if (options.cancelToken) {
    options.cancelToken.promise.then((reason) => {
      requestTask.abort();
      reject(reason);
    });
  }
};

const get = (url, params, config = {}) => {
  return request({
    url,
    method: "GET",
    params,
    ...config,
  });
};

const post = (url, data, config = {}) => {
  return request({
    url,
    method: "POST",
    data,
    ...config,
  });
};

const put = (url, data, config = {}) => {
  return request({
    url,
    method: "PUT",
    data,
    ...config,
  });
};

const del = (url, data, config = {}) => {
  return request({
    url,
    method: "DELETE",
    data,
    ...config,
  });
};

export default {
  request,
  refreshToken,
  get,
  post,
  put,
  delete: del,
};
